Marginal → X-Plane Scenery → Tools → GroundTraffic |
This kit allows X-Plane scenery designers to add animated ground vehicle traffic to airport scenery packages. It requires X-Plane 10.0 or later.
This kit supplies a plugin that you can distribute with your scenery package. The plugin reads instructions from a text file that you create (and which you should also distribute with your scenery package) and animates X-Plane scenery objects according to those instructions. The objects to be animated can come from X-Plane's built-in library, from an add-on object library (e.g. OpenSceneryX), or from your scenery package.
Use Notepad, TextEdit, or any other text editor to create a plain text file named GroundTraffic.txt in your scenery package folder. Save this blank file with an “ANSI”, “Western” or “UTF-8” encoding. (If using TextEdit, you may have to first choose Format → Make Plain Text to see those choices).
Add a “Header” statement to this file, followed by one or more “Routes”:
The Header statement tells the plugin the location of your airport. It should be of the form “ICAO lat lon”, where:
For example Seattle-Tacoma airport tower:
KSEA 47.4557260 -122.3013928
A Route statement starts a new animation. It should be of the form “route
speed offset heading object”, where:
For the animation to look correct objects should be modelled such that they are pointing North and are roughly centered at their origin (since the plugin rotates them about their origin).
0
for the “offset” and “heading” values in this statement.For example, a route using an object from the scenery package, travelling at 30km/h (~18mph):
route 30 0 0 objects/airport_fuel_truck.obj ...
A route using an object from X-Plane 10's built-in library, travelling at 24km/h (~15mph), to be rotated 180°:
route 24 0 180 lib/airport/Ramp_Equipment/Luggage_Truck.obj ...
A route using an object from the OpenSceneryX library, travelling at 20km/h (~12mph), shifted forwards 2.5m so that it rotates about its center:
route 20 2.5 0 opensceneryx/objects/airport/vehicles/loaders/6.obj ...
The Route statement should be preceded by a blank line and should be followed by a sequence of “waypoints” and “commands”. The Route ends with a blank line.
Animated objects move from one waypoint to the next at the speed specified in the Route statement. When the object passes the last waypoint it proceeds towards the first waypoint, forming a circular route (unless you specify a “reverse” command).
Waypoints should be of the form “lat lon”. For example:
... 47.4484450 -122.3001950 ...
You can use OverlayEditor or WED to map out your route, typing the the waypoint locations into GroundTraffic.txt as you go. You may also want to consider placing a “line” (e.g. one of opensceneryx/lines/airport/zone_outlines/...
) in OverlayEditor or WED to record your route; this will make it easier if you want to adjust your route in the future. But remember to remove or hide these lines before publishing your scenery package.
Objects will try to avoid crashing into each other by waiting at a waypoint if an object on another route is crossing ahead. So where routes cross don't leave a large distance between the waypoints on either side of the crossing point.
The Pause command instructs the animated object to wait at the preceding waypoint for a while before moving on. Optionally, you can cause the value of a DataRef to change while the animated object is waiting, and change back before it proceeds.
The Pause command should be of the form “pause
time set
name slope curve duration”, where:
set
name slope curve duration (optional)For example, waiting at a waypoint for 30 minutes:
... 47.4629025 -122.3020905 pause 1800 ...
Waiting at a waypoint for one minute while setting the value of the DataRef marginal/groundtraffic/var[0]
such that it rises from 0 to 1 over five seconds, stays at 1, then starts going back to 0 five seconds before the object proceeds:
... 47.4380074 -122.3040742 pause 60 set var[0] rise linear 5 ...
The At command instructs the animated object to wait at the preceeding waypoint until a particular time of day. It should be of the form “at
HH:MM on
days”, where:
For example, an animation that waits until 8am:
... 47.4559849 -122.3028592 at 08:00 ...
An animation that waits until 8am or 8pm on a weekday:
... 47.4559849 -122.3028592 at 08:00 20:00 on Mon Tue Wed Thu Fri ...
The When command instructs the animated object to wait at the preceeding waypoint until a DataRef is within a specified range. (This command is similar in concept to ANIM_show
in .obj files). It should be of the form “when
name from to”, where:
[n]
” to the name.For example, an animation that only takes place in daylight:
... 47.4559849 -122.3028592 when sim/graphics/scenery/percent_lights_on 0 0.2 ...
The Backup command instructs the animated object to reverse from the preceding waypoint as far as the next waypoint, and thereafter move forward as normal. If the preceding waypoint also has a Pause command the object points forwards while waiting, and then backs-up after waiting.
The Backup command just consists of the word “backup
”.
For example backing-up into a parking spot:
... 47.4348468 -122.3034628 backup 47.4349236 -122.3034600 pause 60 47.4348468 -122.3034628 ...
Backing-up after a pause:
... 47.4379349 -122.3040074 47.4380074 -122.3040742 pause 60 backup 47.4379349 -122.3040074 ...
For best results the waypoints before and after backing-up should be at the same location, as in the above examples, or at least in a straight line.
Normally, when the animated object passes the last waypoint it proceeds towards the first waypoint, forming a circular route. The Reverse command instead instructs the object to change direction at the last waypoint and re-trace its steps.
The Reverse command just consists of the word “reverse
” and must be at the end of the Route. For example:
... reverse
Note: You can't use the Reverse command in a route that contains Backup commands.
The Set command causes the value of a DataRef to change when the animated object arrives at the preceding waypoint. It should be of the form “set
name slope curve duration”, where:
var[0]
... var[9]
or the name of a custom DataRef.rise
or fall
- whether the value the DataRef rises from 0.0 to 1.0, or falls from 1.0 to 0.0.linear
or sine
- whether the value the DataRef changes linearly or like ∫ over the duration.0
if you want the DataRef to change value instantly.If you specify a name of the form var[n]
then this command controls the “array” DataRef marginal/groundtraffic/var[n]
, which can be used to drive animations in a 3D modelling application that supports X-Plane animations. Each object will see values for this DataRef that are specific to the route that the object is following; so it is safe to re-use this DataRef across different objects and routes. For example, within one GroundTraffic.txt file, you could use marginal/groundtraffic/var[0]
to control an animated belt in one or more beltloader objects, and also use marginal/groundtraffic/var[0]
to control a refueling animation in one or more fuel truck objects. However, because the values returned for this DataRef are specific to a route, you can't usefully use it in a static object that is placed conventionally within an X-Plane scenery package.
Alternatively you can specify the name of a custom DataRef of your choice, but which should be unique to this scenery package. This DataRef can be used to animate objects that are used in a route and/or static objects that are placed conventionally within an X-Plane scenery package. Because all objects (either static or animated by this plugin) will see the same value for your custom DataRef it doesn't make sense to use the same custom DataRef in more than one route.
For example, setting the value of the DataRef marginal/groundtraffic/var[1]
such that it rises from 0 to 1 over five seconds on hitting a waypoint:
... 47.4380074 -122.3040742 set var[1] rise linear 5 ...
Setting the value of a custom DataRef such that it falls from 1 to 0 over two seconds on hitting a waypoint:
... 47.4348578 -122.3034624 set my/custom/dataref fall sine 2 ...
The “Pause ... set” command also supports changing the value of a custom DataRef when the animated object arrives at a waypoint. The “Pause ... set” command restores the DataRef to its previous value before the object moves on from the waypoint; this command does not.
Lines starting with “#
” are treated as comments and are ignored. For example:
# This is a comment
debug
” and should be preceded by a blank line:
debug
Instead of animating a single object along a Route, you can animate a number of objects to follow each other in succession like train cars/coaches follow their locomotive.
A Train statement starts a description of a train of connected objects. It should be of the form “train
name”, where:
For example a suitable name for a train consisting of a tug and four luggage carts:
train marginal/luggage_train_4 ...
The Train statement should be preceded by a blank line and should be followed by a list of the “Car” statements. The Train description ends with a blank line.
A train Car statement should be of the form “lag offset heading object”, where:
To determine how far an object should lag behind the the lead object you can open/import the objects in your 3D modelling application and measure how far (in metres) you have to move the object behind the lead object for it to appear to “link up” correctly. If either object needs an offset to be centered on its axes then adjust for this before measuring. Repeat the process for further objects.
For example two objects, both of which need to be rotated 180°, the second of which is 3.36m behind the first:
... 0 0 180 lib/airport/Ramp_Equipment/Luggage_Truck.obj 3.36 0 180 lib/airport/Ramp_Equipment/Luggage_Cart.obj ...
The plugin animates train Car objects as if they are connected to each other so don't leave huge gaps between Cars. In particular, if you want to send two or more separate objects down the same route don't (ab)use the Train statement; just duplicate the route and change the order of the waypoints in the copy/copies to space out the objects.
The plugin publishes the following DataRefs that you can use to create animated objects in a 3D modelling application that supports X-Plane animations:
marginal/groundtraffic/distance
marginal/groundtraffic/speed
marginal/groundtraffic/var[0]
... var[9]
marginal/groundtraffic/waypoint/last
marginal/groundtraffic/waypoint/last/distance
marginal/groundtraffic/waypoint/next
marginal/groundtraffic/waypoint/next/distance
These DataRefs return values specific to the route that the object is following; so they are only useful in animating objects on routes controlled by this plugin, not in static objects that are placed conventionally within an X-Plane scenery package. (You can use the “Set” and/or “Pause ... set” commands with a custom DataRef name to publish DataRefs for use in static objects). You can examine the values of these DataRefs using DataRefEditor, but it will only display the values for the first route listed in GroundTraffic.txt.
The speed of rotation of a wheel depends on its size; a smaller wheel needs to rotate more quickly to cover a given distance than a larger wheel. So in your 3D modelling application measure the diameter of the wheel (in metres) and multiple this value by π to obtain the wheel's circumference.
Set up an animation for the wheel containing two keyframes. Rotate the wheel 90° forwards around its axle between the two keyframes. Specify the X-Plane animation values as follows:
marginal/groundtraffic/distance
For example, for a wheel 1.155m in diameter:
marginal/groundtraffic/distance
You can check that the plugin has been loaded and is operating correctly by opening the file Log.txt in the X-Plane folder. You should see:
Fetching plugins for Custom Scenery/my scenery package/plugins
Loaded: Custom Scenery/my scenery package/plugins/GroundTraffic/mac.xpl.
If the plugin is operating correctly it produces no other output in the log. However if the plugin has a problem reading your GroundTraffic.txt file you will see one or more entries starting with “GroundTraffic:” in the log and the plugin will not perform any animation. For example:
GroundTraffic: Empty route at line 15
The plugin examines your GroundTraffic.txt file when you make a selection from the Location → Select Global Airport dialog; if you have edited the file then the plugin will re-read it and re-start the animations. Or you can force the plugin to re-read the file, re-load the objects, and re-start the animations by disabling and re-enabling it in the Plugin → Plugin Admin → Enable/Disable dialog.
“X-Plane” is a registered trademark of Laminar Research.
This kit is licensed under the Creative Commons Attribution license. In short, you can use the plugin provided by this kit in commerical scenery packages, but you must give the author credit.
The author would appreciate a courtesy copy of any commercial scenery that you make using this kit, but you are under no obligation.
Version 1.00 © 2013 Jonathan Harris
![]() |